﻿using A.M.ETO;
using A.M.Storage.Application;
using AutoMapper;
using DotNetCore.CAP;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Public_Class_Library;
using Q.M.Finance.Domain.Entity;
using Q.M.Sell.Application.IServices;
using Q.M.Sell.Doamin.DTO;
using Q.M.Sell.Doamin.Entity;
using Q.M.Sell.Infrastruecure.IRepository;
using Q.M.Sell.Infrastruecure.Repository;
using Redis_ClientInfor;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.DirectoryServices.Protocols;
using System.Drawing.Printing;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Q.M.Sell.Application.Services
{
    public class SalesServices : BaseServices<sales, string>, ISalesServices
    {
        private readonly ISalesRepository salesRepository;
        private readonly IMapper mapper;
        private readonly Cross_service_Helper cross_Service_Helper;
        private readonly ICapPublisher capPublisher;
        private readonly ISales_productRepository sales_ProductRepository;

        public SalesServices(ISalesRepository salesRepository, ISales_productRepository sales_ProductRepository, IMapper mapper, Cross_service_Helper cross_Service_Helper, ICapPublisher capPublisher) : base(salesRepository)
        {
            this.salesRepository = salesRepository;
            this.mapper = mapper;
            this.cross_Service_Helper = cross_Service_Helper;
            this.capPublisher = capPublisher;
            this.sales_ProductRepository = sales_ProductRepository;
        }
        /// <summary>
        /// 添加销售订单
        /// </summary>
        /// <param name="salesAddDTO"></param>
        /// <returns></returns>
        public async Task<ApiReturn<string>> GetsalesAddInfo(salesAddDTO salesAddDTO)
        {
            try
            {
                sales_ProductRepository.BeginTranInfor();
                ApiReturn<string> apiReturn = new ApiReturn<string>();
                var sales = mapper.Map<sales>(salesAddDTO);
                List<sales_product> products = new List<sales_product>();
                foreach (var item in salesAddDTO.products)
                {
                    sales_product sales_Product = new sales_product();
                    sales_Product.sales_number = salesAddDTO.salesid;
                    sales_Product.productid = item.product_number;
                    sales_Product.price = item.unit_sales_price;
                    sales_Product.quantity = item.number;
                    sales.totalmoney = sales_Product.price * sales_Product.quantity;
                    sales.amount_after_concession = sales.totalmoney * (decimal)0.95;
                    sales.amount_received = sales.amount_after_concession * (decimal)0.8;
                    sales.invoiced_amount = sales.amount_received;
                    sales_Product.date_released = item.date_released;
                    sales_Product.productname = item.product_name;
                    sales_Product.specifications_and_models = item.specification_model;
                    sales_Product.unit = item.unit_name;
                    sales_Product.comment = item.comment;
                    products.Add(sales_Product);
                }


                var res1 = cross_Service_Helper.Get("http://10.31.59.5:8002/api/Approval_form/GetShowSystem").Result;
                var geinfor = JsonConvert.DeserializeObject<List<approval_formDTO>>(res1);
                //判断审批状态是否开启
                var xiaos = geinfor.Where(c => c.approval_name == "销售系统").FirstOrDefault();

                if (xiaos.approval_on_no)
                {
                    //如果为开启状态存入Redis中
                    RedisClient.redisClient.HsetInforAsync("DdList", salesAddDTO.salesid, sales);
                    RedisClient.redisClient.HsetInforAsync("DdCList", salesAddDTO.salesid, products);
                    //添加成功需要传一个消息队列  传递哪个模块 还有编号
                    string numberName = "销售系统-" + salesAddDTO.salesid;
                    capPublisher.Publish("GetNewNumber", numberName);
                    apiReturn.Code = 300;
                    apiReturn.Message = "等待审批，审批后自动执行";
                    return apiReturn;
                }
                else
                {
                    //否则直接添加
                    await salesRepository.AddInfor_Async(sales);
                    var res = await sales_ProductRepository.AddInfor_Batch_Async(products);
                    if (res > 0)
                    {
                        sales_ProductRepository.CommitTranInfor();
                        apiReturn.Code = 200;
                        apiReturn.Message = "添加成功";
                        //添加成功需要传一个消息队列  传递哪个模块 还有编号
                        string numberName = "销售系统-" + salesAddDTO.salesid;
                        capPublisher.Publish("GetNewNumber", numberName);
                    }
                    else
                    {
                        apiReturn.Code = 400;
                        apiReturn.Message = "添加失败";

                    }
                    return apiReturn;
                }

            }
            catch (Exception)
            {
                sales_ProductRepository.RollbackTranInfor();
                throw;
            }
        }


        public async Task<ApiReturn<string>> GetAddXsInfor(string? id)
        {
            ApiReturn<string> apiReturn = new ApiReturn<string>();
            var rew = await RedisClient.redisClient.HgetInforAsync<sales>("DdList", id);
            var res1 = await RedisClient.redisClient.HgetInforAsync<List<sales_product>>("DdCList", id);
            await salesRepository.AddInfor_Async(rew);
            var res = await sales_ProductRepository.AddInfor_Batch_Async(res1);
            if(res > 0)
            {
                apiReturn.Code = 200;
                apiReturn.Message = "添加成功";
            }
            return apiReturn;

        }

        /// <summary>
        /// 修改销售订单
        /// </summary>
        /// <param name="salesAddDTO"></param>
        /// <returns></returns>
        public async Task<ApiReturn<string>> GetsalesUpdateInfo(salesUpdateDTO salesUpdateDTO)
        {
            ApiReturn<string> apiReturn = new ApiReturn<string>();
            var id = salesRepository.GetShowInfor(x => x.salesid.Equals(salesUpdateDTO.salesid));
            foreach (var item in id)
            {
                item.salesid = salesUpdateDTO.salesid;
                item.sales_order_subject = salesUpdateDTO.sales_order_subject;
                item.customer_name = salesUpdateDTO.customer_name;
                item.sales_date = salesUpdateDTO.sales_date;
                item.product_summary = salesUpdateDTO.product_summary;
                item.totalmoney = salesUpdateDTO.totalmoney;
                item.amount_after_concession = salesUpdateDTO.amount_after_concession;
                item.amount_received = salesUpdateDTO.amount_received;
                item.invoiced_amount = salesUpdateDTO.invoiced_amount;
            }
            var res = await salesRepository.UpdInfor_Batch_Async(id);
            if (res > 0)
            {
                apiReturn.Code = 200;
                apiReturn.Message = "修改成功";
            }
            return apiReturn;
        }
        /// <summary>
        /// 反填销售订单
        /// </summary>
        /// <param name="salesid"></param>
        /// <returns></returns>
        public async Task<sales> FindsalesInfo(string? salesid)
        {
            Expression<Func<sales, bool>> i = c => c.salesid == salesid;
            var sales = salesRepository.GetShowObj(i);
            return sales;

        }

        /// <summary>
        /// 删除销售订单
        /// </summary>
        /// <param name="salesid"></param>
        /// <returns></returns>
        public async Task<ApiReturn<string>> Deletesales(string? salesid)
        {
            try
            {
                salesRepository.BeginTranInfor();
                ApiReturn<string> apiReturn = new ApiReturn<string>();
                //删主表
                var res = await salesRepository.GetShowObjAsync(x => x.salesid == salesid);
                var list = await salesRepository.DelInfor_Async(res);
                //删子表
                var res2 = (await sales_ProductRepository.GetShowQueryableAsync(x => x.sales_number == res.salesid)).ToList();
                if (res2.Count() != 0)
                {
                    await sales_ProductRepository.DelInfor_Batch_Async(res2);
                }
                salesRepository.CommitTranInfor();
                apiReturn.Code = 200;
                apiReturn.Message = "删除成功";
                return apiReturn;
            }
            catch (Exception)
            {
                salesRepository.RollbackTranInfor();
                throw;
            }

        }

        /// <summary>
        /// 销售订单显示+分页+查询
        /// </summary>
        /// <param name="minMoney"></param>
        /// <param name="maxMoney"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public PageETO<salesShowDTO> GetsalesInfo(string? salesid, string? stock_removal, int pageIndex, int pageSize)
        {
            PageETO<salesShowDTO> pageETO = new PageETO<salesShowDTO>();
            Expression<Func<sales, bool>> wherexp = i => true;
            if (!string.IsNullOrEmpty(salesid))
            {
                wherexp = i => i.salesid == salesid || i.sales_order_subject.Contains(salesid);
            }
            if (!string.IsNullOrEmpty(stock_removal))
            {
                wherexp = i => i.stock_removal.Equals(stock_removal);
            }
            var res1 = cross_Service_Helper.Get("http://10.31.59.4:8023/api/Client_payer_informationWrite/GetpayerInfo").Result;
            var obj = JsonConvert.DeserializeObject<List<client_payer_information>>(res1);
            var list = salesRepository.GetShowInforOrder(wherexp, x => x.selldate);
            var selprim = sales_ProductRepository.GetShowInfor();
            var res = (from a in list
                       join c in obj on a.customer_name equals c.customer_name
                       select new salesShowDTO
                       {
                           salesid = a.salesid,
                           sales_order_subject = a.sales_order_subject,
                           customer_name = c.customer_name,
                           sales_date = a.sales_date,
                           product_summary = a.product_summary,
                           stock_removal = a.stock_removal,
                           make_out_an_invoice = a.make_out_an_invoice,
                           gathering = a.gathering,
                       }).Distinct().ToList();
            foreach (salesShowDTO item in res)
            {
                var sellist = selprim.Where(c => c.sales_number == item.salesid).ToList();
                decimal money = 0;
                foreach (var sel in sellist)
                {
                    money += sel.price * sel.quantity;
                }
                item.totalmoney = money;
                item.amount_after_concession = (money * (decimal)0.95);
                item.amount_received = item.amount_after_concession * (decimal)0.8;
                item.invoiced_amount = item.amount_received;
            }

            pageETO.TotalCount = res.Count();
            pageETO.PageCount = (int)Math.Ceiling(pageETO.TotalCount * 1.0 / pageSize);
            pageETO.Data = res.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }
        /// <summary>
        /// 根据销售单号反填付款方信息
        /// </summary>
        /// <param name="salesid"></param>
        /// <returns></returns>
        public client_payer_information GetInfo(string salesid)
        {
            var res1 = cross_Service_Helper.Get("http://10.31.59.4:8023/api/Client_payer_informationWrite/GetpayerInfo").Result;
            var obj = JsonConvert.DeserializeObject<List<client_payer_information>>(res1);
            var list = salesRepository.GetShowInfor();
            var res = (from a in list
                       join b in obj on a.customer_name equals b.customer_name
                       where a.salesid == salesid
                       select b).FirstOrDefault();
            return res;
        }


    }
}
